<html>

<head>
    <title>本地图片转化为灰度图片</title>
    <style>
        .section {
            border: 1px solid red;
            min-height: 500px;
        }
        .canvas {
            border: 1px solid gray;
        }
    </style>
</head>

<body>
    <div>
        <h3>点击按钮添加图片，或者直接粘贴图片（如copy + v）</h3>
        <input type="file" id="upload" accept="image/*" />
        <br />
        <br />
    </div>
    <div class="section">     
        <img id="img" src="Canvas_art_gallery.jpeg" alt="图片" />
    </div>
    <hr>
    <div class="canvas">
        <canvas id="myCanvas"></canvas>
        <div>
            <br />
            <br />
            <button id="downloadBtn">下载灰度图片</button>
        </div>
    </div>
    <script>
        // input监听上传
        const $upload = document.querySelector('#upload');
        $upload.onchange = function (evt) {
            const file = evt.target.files[0];
            myCanvas.setImgByFileReader(file, (img) => {
                myCanvas.imgToGrayCanvas(img)
            })
        }
        
        function MyCanvas () {
            this.setImgByFileReader = function (file, grayImgHandler) {
                const reader = new FileReader();
                reader.onload = function (e) {
                    const $img = document.querySelector('#img');
                    $img.src = e.target.result;
                    $img.onload = function () {
                        grayImgHandler($img);
                    }
                };
                reader.onerror = function (err) {
                    console.log(err);
                };
                reader.readAsDataURL(file);
            };

            this.imgToGrayCanvas = function imgToGrayCanvas(imgEle) {
                const canvas = this.getCanvasEle();
                const context = canvas.getContext('2d');
                canvas.height = imgEle.height;
                canvas.width = imgEle.width;
                context.drawImage(img, 0, 0);

                // 转化为灰度图
                const imgData = context.getImageData(0, 0, canvas.width, canvas.height);
                const data = imgData.data;
                for (let i = 0; i < data.length; i+=4) {
                    const average = (data[i] + data[i + 1] + data[i + 2]) / 3;
                    data[i] = average;
                    data[i + 1] = average;
                    data[i + 2] = average;
                }
                context.putImageData(imgData, 0, 0);
                return canvas.toDataURL();
            };
            this.getCanvasEle = function () {
                return document.querySelector('#myCanvas');
            };
            this.download = function () {
                const a = document.createElement('a');
                console.log('this.getCanvasEle().toDataURL()::', this.getCanvasEle().toDataURL());
                a.href = this.getCanvasEle().toDataURL();
                a.download = 'gray';
                document.body.appendChild(a);
                a.click();
                setTimeout(() => {
                    a.parentNode.removeChild(a);
                }, 1000)
            }
        }
        

        // 粘贴图片
        document.body.onpaste = (evt) => {
            this.pasteContent = evt.clipboardData.getData("text/plain");
            const items = evt.clipboardData.items;
            if (items) {
                for (let i = 0; i < items.length; i++) {
                    const item = items[i];
                    if (item.type.includes('image')) {
                        let file = item.getAsFile();
                        myCanvas.setImgByFileReader(file, (img) => {
                            myCanvas.imgToGrayCanvas(img);
                        })
                    }
                }
            }
        }

        // 初始化
        const myCanvas = new MyCanvas();
        const $img = document.querySelector('#img');
        $img.onload = function () {
            myCanvas.imgToGrayCanvas($img);
        }

        const $downloadBtn = document.querySelector('#downloadBtn');
        $downloadBtn.onclick = function () {
            myCanvas.download();
        }
    </script>
</body>

</html>